﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using XEngine;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Xna.Framework.Input;

namespace X_Editor
{
    public class RenderControl : GraphicsDeviceControl
    {
        Timer redraw;
        XMain x;
        public XMain X
        {
            get { return x; }
            set { 
                if (x != null) 
                {
                    List<XComponent> remove = new List<XComponent>();

                    foreach (XComponent comp in x.Components)
                        remove.Add(comp);

                    foreach (XComponent rem in remove)
                    {
                        x.Components[x.Components.IndexOf(rem)] = null;
                        x.Components.Remove(rem);
                    }
                    if (x.game != null)
                    {
                        x.game.Dispose();
                        x.game = null;
                    }
                    x.Dispose();
                    x = null;
                } 
                x = value;
            }
        }

        XEditorGameTime time = new XEditorGameTime();

        public XFreeLookCamera camera;
        public XKeyboard keyboard;
        public XMouse mouse;

        public RenderControl()
        {
            redraw = new Timer();
            redraw.Interval = 1;
            redraw.Start();

            redraw.Tick += new EventHandler(redraw_Tick);
        }

        public void Init()
        {
            Initialize();
        }

        protected override void Initialize()
        {
            Game1 Game = new Game1("", graphicsDeviceService);

            if (X != null)
            {
                if (X.game != null)
                    X.game = null;

                X = null;
            }

            X = new XMain(Game);
            X.Initialize();
            X.Physics.EnableFreezing = false;

            time.TotalGameTime.Reset();
            time.TotalGameTime.Start();
            time.ElapsedGameTime.Reset();
            time.ElapsedGameTime.Start();

            hasFocus = false;
            dragdroprelease = false;
        }

        public void SetupBaseComponents()
        {
            camera = new XFreeLookCamera(X);
            keyboard = new XKeyboard(X);
            mouse = new XMouse(X);
            mouse.Reset = false;
        }

        public bool hasFocus = false;
        public bool dragdroprelease = false;

        protected override void Draw()
        {
            GameTime gameTime = new GameTime(time.TotalGameTime.Elapsed, time.ElapsedGameTime.Elapsed, time.TotalGameTime.Elapsed, time.ElapsedGameTime.Elapsed, false);

            X.Update(gameTime);

            //foreach(XComponent component in X.Components)
              //  X.Debug.Write(component.ToString(), false);

            if (hasFocus && keyboard != null && mouse != null)
            {
                if (keyboard.KeyDown(Microsoft.Xna.Framework.Input.Keys.S))
                    camera.Translate(Vector3.Backward * 40);
                if (keyboard.KeyDown(Microsoft.Xna.Framework.Input.Keys.W))
                    camera.Translate(Vector3.Forward * 40);
                if (keyboard.KeyDown(Microsoft.Xna.Framework.Input.Keys.A))
                    camera.Translate(Vector3.Left * 40);
                if (keyboard.KeyDown(Microsoft.Xna.Framework.Input.Keys.D))
                    camera.Translate(Vector3.Right * 40);

                if (mouse.ButtonPressed(XMouse.Buttons.Left))
                {
                    mouse.InitialPosition = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);
                    mouse.CurrentPosition = mouse.InitialPosition;
                    mouse.Delta = Vector2.Zero;
                    mouse.Reset = true;
                    Cursor.Hide();
                }
                else if (mouse.ButtonReleased(XMouse.Buttons.Left))
                {
                    mouse.Reset = false;

                    if (!dragdroprelease)
                        Cursor.Show();
                    else
                        dragdroprelease = false;
                }

                if (mouse.ButtonDown(XMouse.Buttons.Left))
                    camera.Rotate(new Vector3(mouse.Delta.Y * .0016f, mouse.Delta.X * .0016f, 0));
            }

            if (camera != null)
                camera.SetProjection(camera.GenerateProjection(X, MathHelper.PiOver4, X.GraphicsDevice.Viewport.AspectRatio, XCamera.ProjectionType.Perspective));

            X.Renderer.Draw(gameTime, camera);

            time.ElapsedGameTime.Reset();
            time.ElapsedGameTime.Start();
        }

        void redraw_Tick(object sender, EventArgs e)
        {
            Invalidate();
        }
    }

    public class Game1 : Game
    {
        //public ContentManager Content;

        public Game1(string Filename, object GraphicsDeviceService) : base()
        {
            //Content = new ContentManager(Services);
            Content.RootDirectory = Filename;

            Services.AddService(typeof(IGraphicsDeviceService), GraphicsDeviceService);
        }
    }
}
